﻿using System;
using System.Collections.Generic;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
using System.Net;
using System.Web;
using System.Xml;
using ScottLane.MediaFeeder.ObjectModel;

namespace ScottLane.MediaFeeder.WebService
{
    /// <summary>
    /// Partial class of MediaService that implements the Artist related methods.
    /// </summary>
    public partial class MediaService : IMediaService
    {
        /// <summary>
        /// Gets a feed of the specified artist.
        /// </summary>
        /// <param name="name">The artist name.</param>
        /// <returns>The feed</returns>
        public SyndicationFeedFormatter GetArtist(string name)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            if (!Artist.Exists(decodedName))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            Artist artist = new Artist(decodedName);
            SyndicationFeed feed = new SyndicationFeed();
            feed.Title = new TextSyndicationContent(artist.Name);
            feed.Description = new TextSyndicationContent(artist.Name);
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/Artist")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();
            ArtistSyndicationItem item = new ArtistSyndicationItem(artist);
            items.Add(item);
            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public SyndicationFeedFormatter GetArtistAlbums(string name)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            if (!Artist.Exists(decodedName))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            Artist artist = new Artist(decodedName);
            SyndicationFeed feed = new SyndicationFeed();
            feed.Title = new TextSyndicationContent(artist.Name + " Albums");
            feed.Description = new TextSyndicationContent("All albums by " + artist.Name);  // by or containing?
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/ArtistAlbums")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();

            foreach (Album album in artist.Albums)
            {
                AlbumSyndicationItem item = new AlbumSyndicationItem(album);
                items.Add(item);
            }

            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="startIndex"></param>
        /// <param name="maxResults"></param>
        /// <returns></returns>
        public SyndicationFeedFormatter GetArtistSongs(string name, string startIndex, string maxResults)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            if (!Artist.Exists(decodedName))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            int parsedStartIndex = 0;
            int.TryParse(startIndex, out parsedStartIndex);

            int parsedMaxResults = 0;
            int.TryParse(maxResults, out parsedMaxResults);

            Artist artist = new Artist(decodedName);
            SyndicationFeed feed = new SyndicationFeed();
            feed.Title = new TextSyndicationContent(artist.Name + " Songs");
            feed.Description = new TextSyndicationContent("All songs by " + artist.Name);
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/ArtistSongs")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();

            // todo - paging
            foreach (Song song in artist.Songs)
            {
                SongSyndicationItem item = new SongSyndicationItem(song);
                items.Add(item);
            }

            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// Gets a feed containing artists with the specified name.
        /// </summary>
        /// <param name="name">The artist name.</param>
        /// <param name="startIndex">The index of the first artist to include in the results.</param>
        /// <param name="maxResults">The maximum number of artists to return.</param>
        /// <returns>The artist feed.</returns>
        public SyndicationFeedFormatter GetArtists(string name, string startIndex, string maxResults)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            int parsedStartIndex = 0;
            int.TryParse(startIndex, out parsedStartIndex);

            int parsedMaxResults = 0;
            int.TryParse(maxResults, out parsedMaxResults);

            List<Artist> artists = Artist.Search(decodedName, parsedStartIndex, parsedMaxResults);
            SyndicationFeed feed = new SyndicationFeed();

            string feedTitle = "Artist search results";
            string feedDescription = "Search results for artists in the Windows Media Player library";

            if (decodedName == null)
            {
                feedTitle = "All Artists";
                feedDescription = "All artists in the Windows Media Player library";
            }

            feed.Title = new TextSyndicationContent(feedTitle);
            feed.Description = new TextSyndicationContent(feedDescription);
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/Artists")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();

            foreach (Artist artist in artists)
            {
                ArtistSyndicationItem item = new ArtistSyndicationItem(artist);
                items.Add(item);
            }

            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// Plays the artist's songs in Media Center.
        /// </summary>
        public void PlayArtist(string name)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            if (!Artist.Exists(decodedName))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return;
            }

            Artist artist = new Artist(decodedName);
            artist.Play();
        }
    }
}
